package com.linshengjian.snowball.payment.handler;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.linshengjian.snowball.payment.IPaymentHandler;
import com.linshengjian.snowball.payment.PaymentProperties;
import com.linshengjian.snowball.payment.event.PaymentCompleteEvent;
import com.linshengjian.snowball.payment.exception.PaymentBusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
@Component
public class WxpayHandlerImpl implements IPaymentHandler {

    @Autowired
    private ApplicationContext context;

    @Autowired
    protected HttpServletRequest request;

    @Autowired
    protected PaymentProperties properties;

    protected WxPayService wxPayService;

    @PostConstruct
    private void init() {
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(this.properties.getWxPay().getAppId());
        payConfig.setMchId(this.properties.getWxPay().getMchId());
        payConfig.setMchKey(this.properties.getWxPay().getMchKey());
        payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getWxPay().getSubAppId()));
        payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getWxPay().getSubMchId()));
        payConfig.setKeyPath(this.properties.getWxPay().getKeyPath());

        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);

        this.wxPayService = wxPayService;
    }

    @Override
    public Object payment(String voucher, Double amount, String title, String body) throws Exception {
        WxPayUnifiedOrderRequest wxrequest = new WxPayUnifiedOrderRequest();
//        wxrequest.setAppid(payProperties.getAppId());
//        wxrequest.setMchId(payProperties.getMchId());

//        if (StringUtils.isEmpty(openId))
//            throw new BusinessException("没有获取到微信到openid");

//        wxrequest.setOpenid(openId);
        wxrequest.setBody(title);
        wxrequest.setDetail(body);
        wxrequest.setOutTradeNo(voucher);
        wxrequest.setTotalFee(Double.valueOf(amount * 100).intValue());
        wxrequest.setNotifyUrl(properties.getCallbackDomainName() + properties.getCallbackUrl() + "/wxPay");
        wxrequest.setTradeType("APP");
        wxrequest.setSpbillCreateIp(request.getRemoteAddr());

        return wxPayService.createOrder(wxrequest);
    }

    @Override
    public void refund(String refundNo, String paymentNo, Double amount) throws Exception {

        WxPayRefundRequest wxrequest = new WxPayRefundRequest();
        wxrequest.setRefundFee(Double.valueOf(amount * 100).intValue());
        wxrequest.setTotalFee(Double.valueOf(amount * 100).intValue());
        wxrequest.setOutRefundNo(refundNo);
        wxrequest.setOutTradeNo(paymentNo);
        try {

            WxPayRefundResult result = this.wxPayService.refund(wxrequest);

            if ("SUCCESS".equals(result.getReturnCode())) {
                log.info("退款成功，微信单号：" + result.getRefundId());

                PaymentCompleteEvent event = new PaymentCompleteEvent(this, refundNo, result.getRefundId(), new Date());

                context.publishEvent(event);
            }
            throw new PaymentBusinessException("微信退款失败，请联系客服处理");
        } catch (WxPayException e) {
            log.error(e.getMessage(), e);
            throw new PaymentBusinessException(e.getMessage(), null);
        }
    }

    @Override
    public void refresh(String voucher) {

    }

    @Override
    public String callback(HttpServletRequest request, HttpServletResponse response) {
        try {
            String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            WxPayOrderNotifyResult result = wxPayService.parseOrderNotifyResult(xmlResult);

            if (result.getResultCode().equals("SUCCESS")) {
                PaymentCompleteEvent event = new PaymentCompleteEvent(this, result.getOutTradeNo(), result.getTransactionId(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(result.getTimeEnd()));
                context.publishEvent(event);
            }

            return WxPayNotifyResponse.success("处理成功!");
        } catch (Exception e) {
            log.error("微信回调结果异常,异常原因{}", e.getMessage());
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }
}
